Send crossing event due to geometry change in idle
authorAlexander Larsson <alexl@redhat.com>
Thu, 11 Jun 2009 19:49:17 +0000 (21:49 +0200)
committerAlexander Larsson <alexl@redhat.com>
Thu, 11 Jun 2009 19:49:17 +0000 (21:49 +0200)
Doing this directly had some issues with picking going recursive in
clutter-gtk. Furthermore, doing it in an idle means we can coalesce
multiple calls (which is common due to widget changes) in the same
toplevel to just one call.

gdk/gdkinternals.h
gdk/gdkwindow.c

index b6da9bb1dd2a62d5bad41a18934cba8b8d2208b2..cb140068c9dd217d684e60d21f59cc9e759c32f9 100644 (file)
@@ -256,6 +256,7 @@ struct _GdkWindowObject
   GdkRegion *clip_region_with_children; /* Clip region in window coords */
   GdkCursor *cursor;
   gint8 toplevel_window_type;
+  guint synthesize_crossing_event_queued : 1;
   guint effective_visibility : 2;
   guint visibility : 2; /* The visibility wrt the toplevel (i.e. based on clip_region) */
   guint native_visibility : 2; /* the native visibility of a impl windows */
index fae8bbbb2dea653516814272e8273087f18b4352..7c5011218ac1e255129cc4bbff4905231578bf3d 100644 (file)
@@ -8691,18 +8691,22 @@ gdk_window_offscreen_children_changed (GdkWindow *window)
   _gdk_syntesize_crossing_events_for_geometry_change (window);
 }
 
-void
-_gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
+static gboolean
+do_synthesize_crossing_event (gpointer data)
 {
   GdkDisplay *display;
   GdkWindow *changed_toplevel;
+  GdkWindowObject *changed_toplevel_priv;
   GdkWindow *new_window_under_pointer;
   gulong serial;
 
-  display = gdk_drawable_get_display (changed_window);
+  changed_toplevel = data;
+  changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
 
+  display = gdk_drawable_get_display (changed_toplevel);
   serial = _gdk_windowing_window_get_next_serial (display);
-  changed_toplevel = get_event_toplevel (changed_window);
+
+  changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
 
   if (changed_toplevel == display->pointer_info.toplevel_under_pointer)
     {
@@ -8727,6 +8731,33 @@ _gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
          _gdk_display_set_window_under_pointer (display, new_window_under_pointer);
        }
     }
+
+  return FALSE;
+}
+
+void
+_gdk_syntesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
+{
+  GdkDisplay *display;
+  GdkWindow *toplevel;
+  GdkWindowObject *toplevel_priv;
+  GdkWindow *new_window_under_pointer;
+  gulong serial;
+
+  display = gdk_drawable_get_display (changed_window);
+
+  toplevel = get_event_toplevel (changed_window);
+  toplevel_priv = (GdkWindowObject *)toplevel;
+
+  if (toplevel == display->pointer_info.toplevel_under_pointer &&
+      !toplevel_priv->synthesize_crossing_event_queued)
+    {
+      toplevel_priv->synthesize_crossing_event_queued = TRUE;
+      g_idle_add_full (GDK_PRIORITY_EVENTS - 1,
+                      do_synthesize_crossing_event,
+                      g_object_ref (toplevel),
+                      g_object_unref);
+    }
 }
 
 /* Don't use for crossing events */